From Gerard.Galvin


Dear EPE,

Thanks to Peter Hemsley for his comments (Cheats Again Readout Feb '02).
There is always a trade-off in either performance or memory when making code
generic but I'm sure most people will agree that usually the benefits in
flexibility outweigh the performance deficits. Therefore the full 16 bit
division routine would be more useful as generic code than a 10 bit.
Granted, if you were only going to use it for processing the 10 bit ADC on
the PIC 16F877, it is worth making a specific routine.

However, I thought of a little piece of code which helps to optimise the
full 16 bit division routine when being passed numbers less than 16 bit.
I've taken the liberty of attaching the code and an explanation.

Thanks also for pointing me to the Binary-to-Decimal challenge in PICTRICKS.
Maths is not my strong point so I'll be grappling with these routines for a
while yet before I understand them!
 

Code to reduce cycle time when dividing smaller Numbers

Two bytes are still used for the dividend. (The program may not always know how big the numbers are!). My piece of code simply checks the dividend's upper byte to see if it is zero or not. If it is, the upper and lower bytes are swapped and the count reduced by eight. This saves eight redundant Rotations Through Carry. Then the code snippet checks for leading zeros. once again, if there are any these are shifted round and the bit count reduced without the unnecessary comparison part of the algorithm executing.
Below is part of Peter Hemsley's original routine with the place to insert my snippet marked. 


part of Peter Hemsley's original division routine:

	...

divide	movfw	divisL
	iorwf	divisH,w
	skpnz
	goto	div0		;Division by zero !

	movlw	16		;16 bit	division
	movwf	bitcnt
	clrf	remdrH		;Clear remainder
	clrf	remdrL
;------------------------------------------------------------
;	My bit of code goes in here
;-------------------------------------------------------------
dvloop	clrc			;Set quotient bit to 0
	rlf	dividL		;Shift left dividend and quotient
	rlf	dividH		;Msb into carry
	rlf	remdrL		;and then into partial remainder
	rlf	remdrH
	...



;------------------------------------------------------------------
;My piece of code:


	movfw	dividH
	btfss	STATUS,Z	;test high byte for any set bits
	goto	leadoff
eight				;high byte of dividend empty
	movfw	dividL		;Swap the two bytes
	movwf	dividH
	clrf	dividL
	movlw	8		;make the count just 8
	movwf	bitcnt		;this would cut down the number of iterations 
				;to 8
leadoff
	btfsc	dividH,7	;now remove the leading zeros
	goto	dvloop
	clrc
	rlf	dividL
	rlf	dividH
	decf	bitcnt
	goto	leadoff

;----------------------------------------------------------------------
